<template>
  <div class="wrap">
    <template>
      <div class="d-flex align-items-center">
        <!--        传动功率        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivePower')}}：</label>
        <el-input v-model="params.P"
                  type = "number"
                  step = "1"
                  :max = thresholdValues.drivePowerMax
                  :min = thresholdValues.drivePowerMin />
        <label class="label">kw</label>

        <!--    修正功率        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDriveCorrectionPower')}}：</label>
        <el-input v-model="params.Pc"
                  type = "number"
                  step = "1"
                  :disabled="true"/>
        <label class="label">kw</label>
      </div>
      <div class="d-flex align-items-center">
        <!--       主动轮齿数        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivingWheelGearNum')}}：</label>
        <el-input v-model="drivingWheel.gearNum"
                  type = "number"
                  step = "1"
                  :min=drivingWheel.wheelThresholdValues.gearNumMin
                  :max=drivingWheel.wheelThresholdValues.gearNumMax />

        <!--       从动轮齿数        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivenWheelGearNum')}}：</label>
        <el-input v-model="drivenWheel.gearNum"
                  type = "number"
                  step = "1"
                  :min=drivenWheel.wheelThresholdValues.gearNumMin
                  :max=drivenWheel.wheelThresholdValues.gearNumMax />

        <!--       传动比        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDriveRatio')}}：</label>
        <el-input v-model="params.i"
                  :disabled="true"
                  type = "number"
                  step = "1"/>

        <label class="label">r/min</label>
      </div>
      <div class="d-flex align-items-center">
        <!--       主动轮转速        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivingWheelSpeed')}}：</label>
        <el-input v-model="drivingWheel.rotateSpeed"
                  type = "number"
                  step = "1"
                  :min=thresholdValues.rotateSpeedMin
                  :max=thresholdValues.rotateSpeedMax />
        <label class="label">r/min</label>
        <!--       从动轮转速        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivenWheelSpeed')}}：</label>
        <el-input v-model="drivenWheel.rotateSpeed"
                  :disabled="true"
                  type = "number"
                  step = "1"/>
        <label class="label">r/min</label>

        <!--        传动速度        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelDriveSpeed') }}:</label>
        <el-select v-model="params.driveSpeedType">
          <el-option
            v-for="item in typeList.driveSpeedTypeList"
            :disabled="true"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>
        <label class="label">m/s</label>
      </div>
      <!--       工况        -->
      <div class="d-flex align-items-center">
        <!--        主动轮工况        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelDrivingWheelCondition') }}:</label>
        <el-select v-model="drivingWheel.workCondition">
          <el-option
            v-for="item in typeList.drivingWheelConditionTypeList"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>

        <!--         从动轮工况        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelDrivenWheelCondition') }}:</label>
        <el-select v-model="drivenWheel.workCondition">
          <el-option
            v-for="item in typeList.drivenWheelConditionTypeList"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>
      </div>

<!--             链轮类型-->
      <div class="d-flex align-items-center">
        <!--       主动轮        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelDrivingChainWheelType') }}:</label>
        <el-select v-model="drivingWheel.useType">
          <el-option
            v-for="item in typeList.chainWheelTypeList"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>
        <!--       从动轮        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelDrivenChainWheelType') }}:</label>
        <el-select v-model="drivenWheel.useType">
          <el-option
            v-for="item in typeList.chainWheelTypeList"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>
      </div>

      <!--       齿数        -->
      <div class="d-flex align-items-center">
      </div>
      <!--       中空半径        -->
      <div class="d-flex align-items-center">
        <!--       主动轮中空半径        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivingWheelHollowRadius')}}：</label>
        <el-input v-model="drivingWheel.chainWheelBasicParam.dk"
                  type = "number"
                  step = "1"
                  :min=drivingWheel.wheelThresholdValues.hollowRadiusMin
                  :max=drivingWheel.wheelThresholdValues.hollowRadiusMax />
        <label class="label">mm</label>

        <!--       从动轮中空半径        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelDrivenWheelHollowRadius')}}：</label>
        <el-input v-model="drivenWheel.chainWheelBasicParam.dk"
                  type = "number"
                  step = "1"
                  :min=drivenWheel.wheelThresholdValues.hollowRadiusMin
                  :max=drivenWheel.wheelThresholdValues.hollowRadiusMax />
        <label class="label">mm</label>
      </div>

      <!--       链号选取        -->
      <div class="d-flex align-items-center">
        <!--        选取链号        -->
        <label class="el-form-item__label">{{ $t('message.ChainDriveDesignDlg.labelSelectChainNo') }}:</label>
        <el-select v-model="params.selectChainNo">
          <el-option
            v-for="item in typeList.selectChainNoList"
            :key="item.value"
            :label="item.text"
            :value="item.value">
          </el-option>
        </el-select>

        <!--       选取的链条号的节距        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelSelectChainPitch')}}：</label>
        <el-input v-model="chainISOParam.p"
                  :disabled="true"
                  type = "number"
                  step = "1"
                  :min=thresholdValues.chainPitchMin />
        <label class="label">mm</label>
      </div>

      <!--       中心距        -->
      <div class="d-flex align-items-center">
        <!--       初定中心距        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelInitCenterDis')}}：</label>
        <el-input v-model="params.a0"
                  type = "number"
                  step = "1"
                  :min=thresholdValues.initCenterDisMin
                  :max=thresholdValues.initCenterDisMax />
        <label class="label">mm</label>

        <!--       调节中心距        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelModifyCenterDis')}}：</label>
        <el-input v-model="params.delta_a"
                  type = "number"
                  step = "0.001"
                  :min=thresholdValues.modifyCenterDisRatioMin
                  :max=thresholdValues.modifyCenterDisRatioMax />
      </div>

      <!--       中心距        -->
      <div class="d-flex align-items-center">
        <!--       计算中心距        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelCalculateCenterDis')}}：</label>
        <el-input v-model="params.ac"
                  :disabled="true"
                  type = "number"
                  step = "1"/>
        <label class="label">mm</label>
        <!--       实际中心距        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelActualCenterDis')}}：</label>
        <el-input v-model="params.a"
                  :disabled="true"
                  type = "number"
                  step = "1"/>
        <label class="label">mm</label>
      </div>

      <!--       链条节数        -->
      <div class="d-flex align-items-center">
        <!--       小链轮包角        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelAlphaAngle')}}：</label>
        <el-input v-model="params.alpha_1"
                  :disabled="true"
                  type = "number"
                  step = "1" />

        <!--       链长节数        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelChainNodeNum')}}：</label>
        <el-input v-model="params.X"
                  :disabled="true"
                  type = "number"
                  step = "1" />

        <!--       链长长度        -->
        <label class="el-form-item__label">{{$t('message.ChainDriveDesignDlg.labelChainLength')}}：</label>
        <el-input v-model="params.L"
                  :disabled="true"
                  type = "number"
                  step = "1" />
        <label class="label">m</label>
      </div>

    </template>

    <!--    确认和关闭-->
    <div class="btn">
      <el-button
        type="primary"
        size="small"
        :disabled="false"
        @click="confirm">
        {{ $t('message.WingTwistDesignDlg.confirm') }}
      </el-button>
      <el-button
        size="small"
        @click="close">
        {{ $t('message.WingTwistDesignDlg.cancel') }}
      </el-button>
    </div>
  </div>
</template>

<script>
import DialogMixin from "../DialogMixin";
import {chainDriveDesignCommand} from "../../../Command/ChainDriveDesign/ChainDriveDesignCommand";
import {language} from "../../../util/Language";
import {Point} from "../../../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";

//轮子的使用类型
const CHAINWHEELUSETYPE = {
  Driving:0,                                                              //主动轮
  Driven:1,                                                               //从动轮
}
//内外侧区分
const SIDETYPE = {
  Inside:0,                                                               //内侧
  OutSide:1,                                                              //外侧
}
//链轮齿数的范围
const CHAINWHEELTHRESHOLDVALUE = {
  Max:114,
  Min:17
}

//工况
const RUNCONDITIONTYPE = {
  Smoothly:0,
  SlightImpact:1,
  MediumImpact:2,
  SeriousImpact:3,
}
//链轮类型
const CHAINWHEELTYPE = {
  IntegralSteelType:0,
  BellySingleType:1,
  BellyMultiType:2,
}
//当前界面中数值变化的类型
const MODIFYPARAMETERTYPE = {
  ParamNone:"None",
  ParamDrivingWheelGearNum:"DrivingWheelGearNum",                         //主动轮齿数修改
  ParamDrivenWheelGearNum:"DrivenWheelGearNum",                           //从动轮齿数修改
  ParamDrivingRotateSpeedNum:"DrivingRotateSpeedNum",                     //主动轮转速修改
  ParamDrivePower:"DrivePower",                                           //传动功率修改
  ParamDrivingWheelCondition:"DrivingWheelCondition",                     //主动轮工况修改
  ParamDrivenWheelCondition:"DrivenWheelCondition",                       //从动轮工况修改
  ParamChainType:"ChainType",                                             //链条类型修改
  ParamInitCenterDis:"InitCenterDis",                                     //初定中心距修改
  ParamModifyCenterDis:"ModifyCenterDis",                                 //调节中心距修改
  ParamChainNo:"ChainNo",                                                 //链号修改
}
export default {
  mixins: [DialogMixin],
  name: 'ChainDriveDesignDlg',
  data() {
    return {
      params: {
        P:1,                                                 //传动功率
        Pc:10,                                               //修正功率
        i:1,                                                 //传动比i

        selectChainNo:"06B",                                //选取链条号

        a0:320,                                             //初定中心距a0
        a0p:40,                                             //以节距计的初定中心距a0p
        ac:320,                                             //计算中心距ac
        a:320,                                              //实际中心距a
        delta_a:0.003,                                      //中心距调节比例，占实际中心距的比例delta_a

        X:122,                                              //链长节数X
        L:2,                                                //链条长度L

        alpha_1:120,                                        //小链轮包角，需要>=120°

        normal:new THREE.Vector3(0,0,1),            //默认链轮的法向方向
        u:new THREE.Vector3(1,0,0),                 //默认的向右方向
        v:new THREE.Vector3(0,1,0),                 //默认的向上方向
      },

      //初始化主、从动链轮
      drivingWheel:new ChainWheelParam(CHAINWHEELUSETYPE.Driving),
      drivenWheel:new ChainWheelParam(CHAINWHEELUSETYPE.Driven),
      chain:new ChainParam(),


      //阈值组
      thresholdValues: {
        drivePowerMax:1000,                              //传动功率最大值
        drivePowerMin:0.1,                              //传动功率最小值
        rotateSpeedMin:1,                               //主动轮转速最小值
        rotateSpeedMax:10000,                           //主动轮转速最大值

        driveSpeedType:0,                               //传动速度类型

        chainPitchMin:1,                                //链条节距最小值

        initCenterDisMin:30,                            //初定中心距最小值
        initCenterDisMax:60,                            //初定中心距最大值

        modifyCenterDisRatioMin:0.002,                  //中心距调节比例最小值
        modifyCenterDisRatioMax:0.004,                  //中心距调节比例最大值
      },

      //列表组
      typeList: {
        //传动速度类型列表
        driveSpeedTypeList:[
          {text:"<0.6", value: 0},
          {text:"0.6~8", value: 1},
          {text:">8", value: 2},
        ],

        //链轮类型
        chainWheelTypeList:[
          {text:language.getMessage('message.ChainDriveDesignDlg.selectIntegralSteelChainWheel'), value: CHAINWHEELTYPE.IntegralSteelType},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectBellySingleChainWheel'), value: CHAINWHEELTYPE.BellySingleType},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectBellyMultiSteelChainWheel'), value: CHAINWHEELTYPE.BellyMultiType},
        ],

        //主动机工况类型列表
        drivingWheelConditionTypeList:[
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivingConditionRunSmoothly'), value: RUNCONDITIONTYPE.Smoothly},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivingConditionSlightImpact'), value: RUNCONDITIONTYPE.SlightImpact},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivingConditionMediumImpact'), value: RUNCONDITIONTYPE.MediumImpact},
        ],

        //从动机工况类型列表
        drivenWheelConditionTypeList:[
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivenConditionRunSmoothly'), value: RUNCONDITIONTYPE.Smoothly},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivenConditionMediumImpact'), value: RUNCONDITIONTYPE.MediumImpact},
          {text:language.getMessage('message.ChainDriveDesignDlg.selectDrivenConditionSeriousImpact'), value: RUNCONDITIONTYPE.SeriousImpact},
        ],

        selectChainNoList:[],
        chainDataList:[],

      },
      chainISOParam:{
        p:8,                            //节距
        d1:5,                           //滚子直径
        b1:3,                           //内链节内宽
        d2:2.31,                        //销轴直径
        d3:2.36,                        //套筒孔径
        h1:7.37,                        //链条通道高度
        h2:7.11,                        //内链板高度
        h3:7.11,                        //外或中链板高度
        l1:3.71,                        //过度链节尺寸l1
        l2:3.71,                        //过度链节尺寸l2
        c:0.08,                         //过度链节尺寸c
        pt:5.64,                        //排距
        b2:4.77,                        //内链节外宽
        b3:4.9,                         //外链节内宽
        b4:8.6,                         //销轴全宽单排
        b5:14.3,                        //销轴全宽双排
        b6:19.9,                        //销轴全宽三排
        b7:3.1,                         //止锁件附加宽度
        f1:50,                          //测量力单排
        f2:100,                         //测量力双排
        f3:150,                         //测量力三排
        q1:4.4,                         //抗拉载荷单排
        q2:7.8,                         //抗拉载荷双排
        q3:11.1,                        //抗拉载荷三排
      },


      smallWheelNum:CHAINWHEELTHRESHOLDVALUE.Min,           //小链轮齿数
      gearNumCenterDisList:[],                              //用于存储获取的f4(通过齿数获取计算中心距系数)的列表
    };
  },
  mounted() {
    chainDriveDesignCommand.init(500,300,500,() => {
      //获取数据库相关内容信息
      if(!this.getDataLibInfo()){
        //初始化错误，弹出错误提示
        //TODO
        return;
      }

      this.initParams();

    });
  },

  methods: {
    changePluginContainerHeight() {
      chainDriveDesignCommand.changePluginContainerHeight({minWidth: this.$el.clientWidth, maxHeight: this.$el.clientHeight});
    },
    confirm: async function () {

      this.drivingWheel.setName("主动轮");
      this.drivenWheel.setName("从动轮");

      //获取当前链子型号
      this.drivingWheel.setChainWheelISOParam(this.chainISOParam);
      this.drivenWheel.setChainWheelISOParam(this.chainISOParam);

      //计算链轮相关参数
      await this.calculateGearWheelParam();

      //绘制主、从动轮模型
      await this.drivingWheel.drawChainWheelModel();
      await this.drivenWheel.drawChainWheelModel();

      //获取主从动轮的轴心
      let drivingCenterPnt = this.drivingWheel.threeArcLineGearShape.center;
      let drivenCenterPnt = this.drivenWheel.threeArcLineGearShape.center;

      //计算从动轮需要怎么移动可以保证实际中心距符合要求,将主动轮圆心移动到原点，从动轮中心在主动轮正x处
      let drivenWheelMoveVector = new THREE.Vector3(this.params.a, 0, 0);
      drivenWheelMoveVector.sub(drivenCenterPnt);
      await this.drivingWheel.moveFeature(new THREE.Vector3(-drivingCenterPnt.x, -drivingCenterPnt.y, -drivingCenterPnt.z));
      await this.drivenWheel.moveFeature(drivenWheelMoveVector);

      //通过链节数、节距，以及主动轮从动轮上链轮轴点，计算出一条曲线，返回曲线上的点
      let curvePoints = await this.calculateChainTrackCurvePoints(this.drivingWheel.threeArcLineGearShape.center,
        this.drivingWheel.listChainCenterPoint,
        this.drivenWheel.threeArcLineGearShape.center,
        this.drivenWheel.listChainCenterPoint,
        this.drivingWheel.chainWheelRadius,
        this.drivenWheel.chainWheelRadius,
        this.params.X,
        this.chainISOParam.p)

      //依据内链+外链循环创建的方式，绘制链子
      await this.drawChain(curvePoints);

      //await this.close();
    },
    close(){
      chainDriveDesignCommand.closeActiveCmd();
    },
    //初始化相关参数
    initParams(){
      //初始化工况
      this.drivingWheel.workCondition = RUNCONDITIONTYPE.Smoothly;
      this.drivenWheel.workCondition = RUNCONDITIONTYPE.Smoothly;

      //初始化转速、链轮齿数
      this.drivingWheel.setGearNum(25);
      this.drivenWheel.setGearNum(57);
      this.drivingWheel.setRotateSpeed(1140);
      this.drivenWheel.setRotateSpeed(500);

      //链子型号计算
      this.calculateChainType(MODIFYPARAMETERTYPE.ParamChainNo);

      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamNone);
    },
    async drawChain(listPoint){
      //需要保持链子的节点数量为偶数，内外链交替，不采用过渡链节
      if(listPoint.length < 4 || listPoint.length % 2 !== 0){
        return;
      }
      // let newList = [];
      // listPoint.forEach(point => {
      //   newList.push(new THREE.Vector3(point.x * 10,point.y * 10));
      // })
      // listPoint = newList;

      //将链子参数传入
      this.chain.setChainISOParam(this.chainISOParam);
      this.chain.setChainBoardCaveHeight(0.8,0.8);
      //设置内外链板的厚度
      this.chain.setOutChainBoardThickness(0.1);
      this.chain.setInChainBoardThickness(0.1);

      let firstOutsideChain = await this.chain.drawOutsideChain(listPoint[0],listPoint[1],"外链" + 0,false);
      let firstInsideChain = await this.chain.drawInsideChain(listPoint[1],listPoint[2],"内链" + 0);

      await this.createChain(listPoint,firstOutsideChain,firstInsideChain);
    },
    async createChain(listPoint,firstOutsideChain,firstInsideChain){
      //对列表中的控制点进行内链节/外链节的交替安装
      for(let i = 1;i <= listPoint.length / 2 - 1;i++){
      //for(let i = 1;i < listPoint.length;i++){
        //对于之后的组进行移动旋转复制操作
        let nNextNo = 2 * i + 2;
        if(i === listPoint.length / 2 - 1){
          nNextNo = 0;
        }
        let outsideChainTransParam = await chainDriveDesignCommand.calculateTransformParam(listPoint[0],listPoint[1],listPoint[2 * i],listPoint[2 * i + 1]);
        let insideChainTransParam = await chainDriveDesignCommand.calculateTransformParam(listPoint[1],listPoint[2],listPoint[2 * i + 1],listPoint[nNextNo]);

        //外链板复制变换
        let curOutsideChain = await chainDriveDesignCommand.moveFeature(firstOutsideChain,
          outsideChainTransParam.moveDir,
          outsideChainTransParam.moveDis,
          "外链" + i,
          true);

        if(outsideChainTransParam.rotateAngle !== 0){
          //旋转
          curOutsideChain = await chainDriveDesignCommand.rotateFeature(curOutsideChain,
            outsideChainTransParam.rotatePoint,
            outsideChainTransParam.rotateDir,
            outsideChainTransParam.rotateAngle,
            "外链旋转" + i,
            false);
        }

        //内链板复制变换
        let curInsideChain = await chainDriveDesignCommand.moveFeature(firstInsideChain,
          insideChainTransParam.moveDir,
          insideChainTransParam.moveDis,
          "内链" + i,
          true);
        if(insideChainTransParam.rotateAngle !== 0){
          //旋转
          curInsideChain = await chainDriveDesignCommand.rotateFeature(curInsideChain,
            insideChainTransParam.rotatePoint,
            insideChainTransParam.rotateDir,
            insideChainTransParam.rotateAngle,
            "内链旋转" + i,
            false);
        }
      }
    },
    //参数计算
    calculateCoefficient(modifyParamType){
      //功率计算
      this.calculateCorrectionPower(modifyParamType);
      //传动比计算
      this.calculateDriveRatio(modifyParamType)
      //链子型号计算
      this.calculateChainType(modifyParamType);

      //计算初定中心距
      this.calculateInitCenterDis(modifyParamType);

      //链长计算
      this.calculateChainNodeLength(modifyParamType);

      //计算计算中心距
      this.calculateCalCenterDis(modifyParamType);

      //计算实际中心距
      this.calculateActualCenterDis(modifyParamType);

      //计算链条速度
      this.calculateChainSpeed(modifyParamType);

      //验证小链轮最小包角
      this.calculateSmallGearWrappingAngle();
    },

    getDataLibInfo() {
      //通过数据库获取链号数据，暂时使用赋值方式
      this.typeList.selectChainNoList = [
        {text:"05B",value:"05B"},
        {text:"06B",value:"06B"}
      ]

      //获取数据库中链号相关数据
      this.typeList.chainDataList = {
        "05B":{
          name:"05B",
          p:8,d1:5,b1:3,d2:2.31,d3:2.36,h1:7.37,h2:7.11,h3:7.11,l1:3.71,l2:3.71,c:0.08,pt:5.64,
          b2:4.77,b3:4.9,b4:8.6,b5:14.3,b6:19.9,b7:3.1,f1:50,f2:100,f3:150,q1:4.4,q2:7.8,q3:11.1
        },
        "06B":{
          name:"06B",
          p:9.525,d1:6.35,b1:5.72,d2:3.28,d3:3.33,h1:8.52,h2:8.26,h3:8.26,l1:4.32,l2:4.32,c:0.08,pt:10.24,
          b2:8.53,b3:8.66,b4:13.5,b5:23.8,b6:34,b7:3.3,f1:70,f2:140,f3:210,q1:8.9,q2:16.9,q3:24.9
        },
      }

      if(this.typeList.selectChainNoList.length === 0 || this.typeList.chainDataList.length === 0){
        return false;
      }
      return true;
    },
    calculateDriveRatio(modifyParamType){
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingRotateSpeedNum){
        return;
      }
      //计算传动比
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingRotateSpeedNum){
        this.params.i = chainDriveDesignCommand.restoreDecimal(this.drivenWheel.gearNum / this.drivingWheel.gearNum,2);
      }
      //小链轮齿数
      this.smallWheelNum = this.params.i > 1 ? this.drivingWheel.gearNum : this.drivenWheel.gearNum;
      this.drivenWheel.rotateSpeed = chainDriveDesignCommand.restoreDecimal(this.drivingWheel.rotateSpeed / this.params.i,2);
    },
    //链轮齿数计算
    calculateGearNum(modifyParamType){
      //未更改齿轮参数不进行重新计算
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum){
        return true;
      }

      //如果主动轮或从动轮齿轮数量超限，应该返回不进行计算
      if(this.drivingWheel.gearNum< CHAINWHEELTHRESHOLDVALUE.Min || this.drivingWheel.gearNum > CHAINWHEELTHRESHOLDVALUE.Max ||
        this.drivenWheel.gearNum < CHAINWHEELTHRESHOLDVALUE.Min || this.drivenWheel.gearNum > CHAINWHEELTHRESHOLDVALUE.Max ){
        return false;
      }

      //根据主/从动轮齿数计算从/主动轮齿数
      if(modifyParamType === MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum){
        this.drivenWheel.gearNum = Math.round(this.drivingWheel.gearNum * this.params.i);
      }else if(modifyParamType === MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum){
        this.drivingWheel.gearNum = Math.round(this.drivenWheel.gearNum / this.params.i);
      }


      return true;
    },

    ///修正功率计算
    calculateCorrectionPower(modifyParamType){
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivePower
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelCondition
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelCondition
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum){
        return;
      }

      //计算工况系数、齿数系数
      let workConditionCoefficient = this.calculateConditionCoefficient();
      let gearNumCoefficient = this.calculateGearNumCoefficient();

      //修正功率计算
      this.params.Pc = chainDriveDesignCommand.restoreDecimal(this.params.P * workConditionCoefficient * gearNumCoefficient,2);
    },

    //计算工况系数
    calculateConditionCoefficient(){
      let conditionCoefficientList = [[1.0,1.1,1.3],
                                    [],             //由于从动机无轻微冲击状况，使用空列表进行占行
                                    [1.4,1.5,1.7],
                                    [1.8,1.9,2.1]];
      return conditionCoefficientList[this.drivenWheel.workCondition][this.drivingWheel.workCondition];
    },

    //齿数系数，通过小链轮齿数获取
    calculateGearNumCoefficient(){
      let gearNumCoefficient = Math.pow(19 / this.smallWheelNum,1.08);

      //小链轮齿数获取到齿数系数
      return gearNumCoefficient;
    },

    //根据链号获取其属性内容, 暂时使用编码代替，之后使用数据库进行内容获取
    calculateChainType(modifyParamType){
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo){
        return;
      }

      let chainProp;
      if(this.typeList.chainDataList[this.params.selectChainNo]){
        chainProp = this.typeList.chainDataList[this.params.selectChainNo];
      }

      this.chainISOParam = chainProp;
    },

    //初定中心距计算
    calculateInitCenterDis(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动初定中心距的范围
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo){
        return;
      }

      //传动比计算，大链轮比小链轮
      let tempDriveRatio = this.drivingWheel.gearNum / this.drivingWheel.gearNum;
      if(tempDriveRatio < 1){
        tempDriveRatio = 1 / tempDriveRatio;
      }

      //计算中心距的最小最大值
      if(tempDriveRatio < 4){
        this.thresholdValues.initCenterDisMin = 0.2 * this.smallWheelNum * (tempDriveRatio + 1) * this.chainISOParam.p;
      }else{
        this.thresholdValues.initCenterDisMin = 0.33 * this.smallWheelNum * (tempDriveRatio - 1) * this.chainISOParam.p;
      }
      this.thresholdValues.initCenterDisMax = 80 * this.chainISOParam.p;
    },

    //链长计算，计算得到的节数值，应化整为偶数，以避免使用过度链节，否则其极限拉伸载荷为正常值的80%，
    calculateChainNodeLength(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动链长的大小
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamInitCenterDis){
        return;
      }

      //计算链条节数系数
      let chainNodeNumCoefficient = Math.pow((this.drivenWheel.gearNum - this.drivenWheel.gearNum) / (2 * Math.PI),2);

      //根据根据链条节数公式X = (z1 + z2) / 2 + 2 * a0 / p + f3 * p / a0,得到列长节数
      let X = (this.drivingWheel.gearNum + this.drivenWheel.gearNum) / 2 +
        2 * this.params.a0 / this.chainISOParam.p +
        chainNodeNumCoefficient * this.chainISOParam.p / this.params.a0;

      //得到的链条节数进行化整处理，且应为偶数
      this.params.X = Math.ceil(X / 2 ) * 2;

      //链条长度计算
      this.params.L = chainDriveDesignCommand.restoreDecimal(this.params.X * this.chainISOParam.p / 1000,2);
    },

    //计算中心距计算
    calculateCalCenterDis(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动计算中心距的大小
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamInitCenterDis){
        return;
      }

      if(this.drivingWheel.gearNum === this.drivenWheel.gearNum){
        //主动轮齿数=从动轮齿数时，使用a = p / 2 * (X -zs)
        this.params.ac = this.chainISOParam.p / 2 * (this.params.X - this.smallWheelNum);
      }else{
        //获取计算中心距系数f4
        //计算(X - zs)/(Z2 - Z1)
        let gearNumCalValue = (this.params.X - this.smallWheelNum) /
          (Math.abs(this.drivingWheel.gearNum - this.drivenWheel.gearNum));

        //获取 齿数计算计算中心距系数
        //let calCenterDisCoefficient = this.getGearNumCalCenterDisCoefficient(gearNumCalValue);
        let calCenterDisCoefficient = this.calculateF4ByTwoSplit(gearNumCalValue);
        if(calCenterDisCoefficient){
          //通过a = p * f4 * (2X - z1 -z2)计算计算中心距
          this.params.ac = chainDriveDesignCommand.restoreDecimal(this.chainISOParam.p * calCenterDisCoefficient *
            (2 * this.params.X - this.drivingWheel.gearNum - this.drivenWheel.gearNum),2);
        }else{
          return false;
        }
      }

      return true;
    },

    //获取齿数计算计算中心距系数
    getGearNumCalCenterDisCoefficient(gearNumCalValue){
      //应该将对应的值算入数据库中，暂时先采用手输录入
      if(this.gearNumCenterDisList.length === 0){
        this.gearNumCenterDisList = {
          13:0.24991,
          12:0.24990
        }
      }

      let coefficient = this.gearNumCenterDisList[gearNumCalValue];
      return coefficient;
    },

    //用二分法计算f4
    calculateF4ByTwoSplit(num){
      let f4 = 1;
      let step = 0.5;

      while(true){
        let theta = chainDriveDesignCommand.acos( 1 / (2 * Math.PI * f4 * (2 * num - 1)));
        let invTheta = Math.PI * (num - 1);
        let invTestTheta = chainDriveDesignCommand.tan(theta) - theta * Math.PI / 180;
        if(Math.abs(invTestTheta - invTheta) < 0.0001){
          break;
        }else{
          if(invTestTheta < invTheta)
          {
            f4 = f4 + step;
          }else{
            f4 = f4 - step;
          }
          step *= 0.5;
        }
      }
      return f4;
    },

    //实际中心距计算
    calculateActualCenterDis(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动计算中心距的大小
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamInitCenterDis
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamModifyCenterDis){
        return;
      }
      //为使链条松边有合适的垂度，需将计算中心距减小δa，其垂度f = (0.01 ~ 0.03)ac
      //对中心距可调的δa取最大值，对中心距不可调的无张紧装置的或有冲击振动的传动取最小值
      //实际中心距a = ac - δa ,一般δa = (0.002 ~ 0.004)ac
      //let delta = 0.002;
      this.params.a = chainDriveDesignCommand.restoreDecimal((1 - this.params.delta_a) * this.params.ac,2);
    },

    //链条速度计算
    calculateChainSpeed(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动计算链条速度的大小
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingRotateSpeedNum){
        return;
      }
      //通过v = z1 * n1 * p / (60 * 1000),得到m/s速度
      let chainSpeed = this.drivingWheel.gearNum * this.drivingWheel.rotateSpeed * this.chainISOParam.p / (60 * 1000);

      //获取到的速度进行分类计算
      if(chainSpeed < 0.6){
        this.params.driveSpeedType = 0;
      }else if(chainSpeed <= 8 && chainSpeed >= 0.6){
        this.params.driveSpeedType = 1;
      }else{
        this.params.driveSpeedType = 2;
      }
    },

    //验算小链轮包角
    calculateSmallGearWrappingAngle(modifyParamType){
      //进入类型为主从动轮齿数、链号时，才会驱动小链轮包角的大小
      if(modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamChainNo
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamInitCenterDis
        && modifyParamType !== MODIFYPARAMETERTYPE.ParamModifyCenterDis){
        return;
      }

      this.params.alpha_1 = chainDriveDesignCommand.restoreDecimal(180 - 57.3 * (this.drivingWheel.gearNum - this.drivenWheel.gearNum) *
        this.chainISOParam.p / (this.params.a * Math.PI),2);

      if(this.params.alpha_1 < 120){
        //TODO 最小链轮包角小于120，报错
        debugger;
      }
    },

    //计算滚子链链轮相关参数
    async calculateGearWheelParam(){
      //齿槽形状最大最小值计算，计算齿侧圆弧半径最大最小值，滚子定位圆弧半径最大最小值，滚子定位角最大最小值
      //this.calculateGearShapeThreshold(modifyParamType);

      //链轮基本参数计算及主要尺寸
      await this.drivingWheel.calculateGearWheelBasicParam();
      await this.drivenWheel.calculateGearWheelBasicParam();

      //demo使用三圆弧-直线齿形方案进行，也符合齿槽形状最大最小限定
      await this.drivingWheel.calculate3ArcLineGear();
      await this.drivenWheel.calculate3ArcLineGear();

      //轴面齿廓尺寸
      await this.drivingWheel.calculateGearProfileParam();
      await this.drivenWheel.calculateGearProfileParam();

      //链轮结构尺寸计算
      await this.drivingWheel.calculateGearSizeParam();
      await this.drivenWheel.calculateGearSizeParam();
    },

    //计算链子轴点的装配位置，以及主动轮、从动轮旋转的角度、链轮轴点位置
    async calculateChainTrackCurvePoints(center1, list1, center2, list2, radius1, radius2, allNum, chainNodeDis) {
      //链条的走线以圆弧+直线+圆弧+悬链线来定义
      //计算链子的上端在绷紧的时候需要主从动轮旋转的角度，此时保证主动轮为切点契合
      let chainInfo = await this.calculateChainWheelRotateInfo(center1, list1, center2, list2, radius1, radius2, chainNodeDis);

      //旋转当前链轮特征
      await this.drivingWheel.rotateFeature(chainInfo.angle1);
      await this.drivenWheel.rotateFeature(chainInfo.angle2);

      //计算上半端进行悬空的链子节点
      let dir11To21 = chainInfo.tanPoints.tanPoint21.clone().sub(chainInfo.tanPoints.tanPoint11);
      dir11To21.normalize();
      let upPoints = [];
      for(let n = 1;n < chainInfo.chainNodeUp;n++){
        let curPoint = chainInfo.tanPoints.tanPoint11.clone().add(dir11To21.clone().multiplyScalar(n * chainNodeDis));
        upPoints.push(curPoint);
      }

      //找到左链轮相切点左侧最近的一个链轮轴点和右侧相切点右侧最近的恶一个链轮轴点，作为下侧抛物线折线的两个端点
      this.drivingWheel.tanPointNo.down = await chainDriveDesignCommand.calculateNearPointOnSide(chainInfo.tanPoints.tanPoint12, this.drivingWheel.listChainCenterPoint, chainDriveDesignCommand.SIDE.NEGATIVE,center1,  this.params.normal);
      this.drivenWheel.tanPointNo.down = await chainDriveDesignCommand.calculateNearPointOnSide( chainInfo.tanPoints.tanPoint22, this.drivenWheel.listChainCenterPoint, chainDriveDesignCommand.SIDE.POSITIVE,center2, this.params.normal);

      //获取已经用掉的链子，包括左轮结合节数、右轮结合节数、上部绷紧节数
      let usedLeftNodeNum = this.drivingWheel.tanPointNo.down - this.drivingWheel.tanPointNo.up;
      usedLeftNodeNum = usedLeftNodeNum > 0 ? usedLeftNodeNum : (usedLeftNodeNum + this.drivingWheel.gearNum);
      let usedRightNodeNum = this.drivenWheel.tanPointNo.up - this.drivenWheel.tanPointNo.down;
      usedRightNodeNum = usedRightNodeNum > 0 ? usedRightNodeNum : (usedRightNodeNum + this.drivenWheel.gearNum);
      let usedChainNodeNum = chainInfo.chainNodeUp + usedLeftNodeNum + usedRightNodeNum;
      let chainNodeNumDown = allNum - usedChainNodeNum;

      //计算链下半部分链子的半径及分布情况
      let downPoints = [];
      let nMark = 0;
      while(true){
        nMark++;
        if(nMark > 10){
          debugger;
        }
        let pointsInfo = chainDriveDesignCommand.calculatePointPosByGravity(this.drivingWheel.listChainCenterPoint[this.drivingWheel.tanPointNo.down],
          this.drivenWheel.listChainCenterPoint[this.drivenWheel.tanPointNo.down],
          chainNodeNumDown,chainNodeDis);

        //对于下方链条耷拉的比较多的，需要计算在下方交点处的切线方向是否符合实际情况
        let slope1 = pointsInfo.slope1;
        let slope2 = pointsInfo.slope2;

        //当前左右侧链轮上的接触点的斜率
        let leftNextPointNo = this.drivingWheel.tanPointNo.down - 1;
        if(leftNextPointNo < 0){
          leftNextPointNo += this.drivingWheel.gearNum;
        }
        let RightNextPointNo = this.drivenWheel.tanPointNo.down + 1;
        if(RightNextPointNo >= this.drivenWheel.gearNum){
          RightNextPointNo -= this.drivenWheel.gearNum;
        }

        let slopeLeft = chainDriveDesignCommand.calculateSlopeOnTwoPoint(this.drivingWheel.listChainCenterPoint[this.drivingWheel.tanPointNo.down],this.drivingWheel.listChainCenterPoint[leftNextPointNo]);
        let slopeRight = chainDriveDesignCommand.calculateSlopeOnTwoPoint(this.drivenWheel.listChainCenterPoint[this.drivenWheel.tanPointNo.down],this.drivenWheel.listChainCenterPoint[RightNextPointNo]);

        //从左往右斜率应该是逐步增大的
        if(slope1 >= slopeLeft && slope2 <= slopeRight){
          downPoints = pointsInfo.points;
          break;
        }

        //如果左侧斜率减少，应该在左侧将下侧接触点往顺时针方向偏一个
        if(slope1 < slopeLeft){
          this.drivingWheel.tanPointNo.down = leftNextPointNo;
          usedLeftNodeNum--;
          chainNodeNumDown++;
        }

        //如果右侧斜率减少，应该在右侧将下侧接触点往逆时针方向偏一个
        if(slopeRight < slope2){
          this.drivenWheel.tanPointNo.down = RightNextPointNo;
          usedRightNodeNum--;
          chainNodeNumDown++;
        }
      }

      //计算所有需要进行实例化的点,从左轮的上接触点开始，沿逆时针方向计算
      let allPoints = [];
      //左侧链轮咬合点
      for(let leftIndex = 0;leftIndex <= usedLeftNodeNum;leftIndex++){
        let no = this.drivingWheel.tanPointNo.up + leftIndex;
        if(no >= this.drivingWheel.gearNum){
          no -= this.drivingWheel.gearNum;
        }
        //await this.sleep(100);
        let curPoint = this.drivingWheel.listChainCenterPoint[no];
        allPoints.push(curPoint);
      }
      //下侧非咬合点
      for(let downIndex = 0;downIndex < downPoints.length;downIndex++){
        allPoints.push(downPoints[downIndex]);
      }
      //右侧链轮咬合点
      for(let rightIndex = 0;rightIndex <= usedRightNodeNum;rightIndex++){
        let no = this.drivenWheel.tanPointNo.down + rightIndex;
        if(no >= this.drivenWheel.gearNum){
          no -= this.drivenWheel.gearNum;
        }
        //await this.sleep(100);
        allPoints.push(this.drivenWheel.listChainCenterPoint[no]);
      }
      //上侧非咬合点
      for(let upIndex = upPoints.length - 1;upIndex >= 0;upIndex--){
        allPoints.push(upPoints[upIndex]);
      }
      //await chainDriveDesignCommand.createPointSketch(allPoints,8,"Test");

      return allPoints;
    },
    //计算链子的上端在绷紧的时候需要主从动轮旋转的角度，此时保证主动轮为切点契合
    async calculateChainWheelRotateInfo(center1,list1,center2,list2,radius1,radius2,chainNodeDis){
      //首先对以当前位置的主从动轮位置以及对应链轮轴点到对应旋转轴半径的两个圆来计算切点位置
      //如果圆上列表为空，错误
      if(list1.length === 0 || list2.length === 0){
        return;
      }

      //计算相切点
      let tanPoints = chainDriveDesignCommand.calculateTangentPoint(center1,center2,radius1,radius2,this.params.normal)

      //计算主动轮旋转的角度,将主动轮上的链轮轴点调整到相切点
      let angle1 = chainDriveDesignCommand.getPointsAngle(center1,list1[0],tanPoints.tanPoint11,this.params.normal);

      //计算两个相切点的距离，并且计算该距离是否可以整除链节长度
      let tanDis = (tanPoints.tanPoint11.clone().sub(tanPoints.tanPoint21)).length();
      //在切点距离上的完整链节数
      let nChainNodeNum =  Math.floor(tanDis / chainNodeDis);
      let remainder = tanDis - nChainNodeNum * chainNodeDis;

      let angle2 = 0;
      //对于不为整的进行处理
      if(remainder > 0.001){
        //通过主动轮在半径为 nChainNodeNum + 1链节长度范围内，为另一个相切点的实际位置
        let intersectPoint = chainDriveDesignCommand.getIntersectPoints(tanPoints.tanPoint11,center2,(nChainNodeNum + 1) * chainNodeDis,radius2,this.params.normal);
        angle2 = chainDriveDesignCommand.getPointsAngle(center2,list2[0],intersectPoint,this.params.normal);
      }
      let calculateInfo = {
        angle1:angle1,
        angle2:angle2,
        chainNodeUp:nChainNodeNum + 1,
        tanPoints:tanPoints
      }
      return calculateInfo;
    },


  },
  watch: {
    "drivingWheel.gearNum": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivingWheelGearNum);
    },
    "drivenWheel.gearNum": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivenWheelGearNum);
    },
    "drivingWheel.rotateSpeed": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivingRotateSpeedNum);
    },
    "params.P": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivePower);
    },
    "drivingWheel.workCondition": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivingWheelCondition);
    },
    "drivenWheel.workCondition": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamDrivenWheelCondition);
    },
    "params.selectChainNo": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamChainNo);
    },
    "params.a0": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamInitCenterDis);
    },
    "params.delta_a": function () {
      this.calculateCoefficient(MODIFYPARAMETERTYPE.ParamModifyCenterDis);
    },

  },
};
export class ChainWheelParam{
  constructor(useType) {
    this.useType = useType;                           //类型
    this.workCondition = RUNCONDITIONTYPE.Smoothly;   //工作环境
    this.feature = null;                              //当前链轮特征
    this.listChainCenterPoint = [];                   //链轮上链条轴所在的位置，链轮轴点列表,列表顺序是逆时针排列
    this.chainWheelRadius = 1;                        //当前链轮的半径，是轴心到链轮轴点的距离

    //链条与链轮的相接链轮轴点序号，分为上侧和下侧，序号值会随着计算的时候进行逼近变化，但是对应的点顺序不会变化，只是用来记录相对位置关系/阶段用的链条数量
    this.tanPointNo = {
      up:0,
      down:0,
    }

    //链轮的最大最小值
    this.wheelThresholdValues = {
      gearSideFilletRadiusMax: 1,                     //齿侧圆弧半径最大值
      gearSideFilletRadiusMin: 1,                     //齿侧圆弧半径最小值
      rollerPosAngleMax: 1,                           //滚子定位角最大值
      rollerPosAngleMin: 1,                           //滚子定位角最小值
      rollerPosArcRadiusMax: 1,                       //滚子定位圆弧半径最大值
      rollerPosArcRadiusMin: 1,                       //滚子定位圆弧半径最小值

      gearNumMax:114,                                 //链轮齿数最大值
      gearNumMin:17,                                  //链轮齿数最小值

      hollowRadiusMin:0,                              //中空半径最小值
      hollowRadiusMax:10,                             //中空半径最大值

    };

    //1.三圆弧直线齿槽形状
    this.threeArcLineGearShape = {
      ri:1,                                             //齿沟圆弧半径r1
      r2:1,                                             //工作段圆弧半径r2
      halfAlpha:1,                                      //齿沟半角α/2
      M:1,                                              //工作段圆弧中心O2的坐标M
      T:1,                                              //工作段圆弧中心O2的坐标T
      beta:1,                                           //工作段圆弧中心角β
      W:1,                                              //齿顶圆弧中心O3的坐标W
      V:1,                                              //齿顶圆弧中心O3的坐标V
      halfGama:1,                                       //齿形半角γ/2
      r3:1,                                             //齿顶圆弧半径r3
      bc:1,                                             //工作段直线部分长度bc
      H:1,                                              //e点至齿勾圆弧中心连线的距离H
      e:new THREE.Vector3(),                            //e点坐标
      center:new THREE.Vector3(),                       //链轮中心点坐标
    };

    //链轮基本参数
    this.chainWheelBasicParam = {
      d:1,                                                //分度圆直径d
      da:1,                                               //齿顶圆直径da
      df:1,                                               //齿根圆直径df
      ha:1,                                               //分度圆弦齿高ha
      Lx:1,                                               //最大齿根距离Lx
      dg:1,                                               //齿侧凸缘(或排间槽)直径dg
      dk:10,                                               //中间空洞大小
      chainWheelPlatformThickness:1                       //链轮厚度
    };

    //轴面齿廓尺寸
    this.chainWheelProfileParam = {
      bf1:1,                                                //齿宽bf1
      bfn:1,                                                //链轮齿总宽bfn
      rx:1,                                                 //齿侧半径rx
      ba:1,                                                 //齿测倒角ba
      ra:1,                                                 //齿侧凸缘(或排间槽)圆角半径ra
    };

    //整体式钢制小链轮参数
    this.integralSteelSprocketParam = {
      h:1,                                                  //轮毂厚度h
      l:1,                                                  //轮毂长度
      dh:1,                                                 //轮毂直径
      //bf，齿宽：在轴面齿廓尺寸中
    };

    //腹板式单排铸造链轮
    this.bellySingleCastingSprocketParam = {
      h:1,                                                  //轮毂厚度h
      l:1,                                                  //轮毂长度
      dh:1,                                                 //轮毂直径
      br:1,                                                 //齿侧凸缘宽度br
      //轮缘部分尺寸
      c1:1,
      c2:1,
      f:1,
      g:1,
      R:1,                                                   //圆角半径R
      t:1,                                                   //腹板厚度
    };

    //腹板式多排铸造链轮
    this.bellyMultiCastingSprocketParam = {
      h:1,                                                  //轮毂厚度h
      l:1,                                                  //轮毂长度
      dh:1,                                                 //轮毂直径
      br:1,                                                 //齿侧凸缘宽度br
      //轮缘部分尺寸
      c1:1,
      c2:1,
      f:1,
      g:1,
      R:1,                                                   //圆角半径R
      t:1,                                                   //腹板厚度
    };

    //默认值
    this.gearNum = 19;                                        //齿轮数
    this.chainRowNum = 1;                                     //链轮排数
    this.chainWheelType = CHAINWHEELTYPE.IntegralSteelType;   //链轮类型
    this.chainWheelName = "链轮";
    this.rotateSpeed = 100;                                   //链轮转速

  }
  setName(name)
  {
    this.chainWheelName = name;
  }
  setGearNum(num){
    //设置链轮齿数
    this.gearNum = num;
  }
  setChainWheelISOParam(param){
    //设置链子规格
    this.chainISOParam = param;
  }
  setChainRowNum(num){
    //设置链轮排数
    this.chainRowNum = num;
  }
  setChainWheelType(type){
    //设置链轮类型
    this.chainWheelType = type;
  }
  setChainWheelHoleDiameter(diameter){
    //设置链轮中心孔径
    this.chainWheelDiameter = diameter;
  }
  setRotateSpeed(speed){
    this.rotateSpeed = speed;
  }

  calculateGearWheelBasicParam() {
    //基本参数有链轮齿数z，配用链条的节距p，配用链条的棍子外径d1，配用链条的排距pt
    //主要尺寸包括分度圆直径d，齿顶圆直径da，齿根圆直径df，分度圆弦齿高ha，最大齿根距离Lx，齿侧凸缘（或排槽间)直径dg
    //其中da、dg计算值取整数舍小数，其他尺寸精确到0.01mm

    this.chainWheelBasicParam.d = this.chainISOParam.p / (chainDriveDesignCommand.sin(180 / this.gearNum));
    this.chainWheelBasicParam.da = Math.round(this.chainISOParam.p * (0.54 + 1 / chainDriveDesignCommand.tan(180 / this.gearNum)));
    this.chainWheelBasicParam.df = this.chainWheelBasicParam.d - this.chainISOParam.d1;
    this.chainWheelBasicParam.ha = 0.27 * this.chainISOParam.p;
    this.chainWheelBasicParam.lx = (this.gearNum % 2) === 0 ? this.chainWheelBasicParam.df : this.chainWheelBasicParam.d * chainDriveDesignCommand.cos(90 / this.gearNum) - this.chainISOParam.d1;
    this.chainWheelBasicParam.dg = Math.round(this.chainISOParam.p / chainDriveDesignCommand.tan(180 / this.gearNum) - 1.04 * this.chainISOParam.h2 - 0.76);
  }

  //计算三圆弧一直线齿槽形状
  calculate3ArcLineGear(){
    //计算齿沟圆弧半径ri、工作段圆弧半径r2
    this.threeArcLineGearShape.ri = 0.5025 * this.chainISOParam.d1 + 0.05;
    this.threeArcLineGearShape.r2 = 1.3025 * this.chainISOParam.d1 + 0.05;

    this.threeArcLineGearShape.halfAlpha = 55 - 60 / this.gearNum;

    //主动轮工作段圆弧中心O2坐标
    this.threeArcLineGearShape.M = 0.8 * this.chainISOParam.d1 * chainDriveDesignCommand.sin(this.threeArcLineGearShape.halfAlpha);
    this.threeArcLineGearShape.T = 0.8 * this.chainISOParam.d1 * chainDriveDesignCommand.cos(this.threeArcLineGearShape.halfAlpha);
    //主动轮齿顶圆弧中心O3的坐标
    this.threeArcLineGearShape.W = 1.3 * this.chainISOParam.d1 * chainDriveDesignCommand.cos(180 / this.gearNum);
    this.threeArcLineGearShape.V = 1.3 * this.chainISOParam.d1 * chainDriveDesignCommand.sin(180 / this.gearNum);

    //主动轮工作段圆弧中心角β
    this.threeArcLineGearShape.beta = 18 - 56 / this.gearNum;

    //主动轮计算齿形半角γ/2
    this.threeArcLineGearShape.halfGama = 17 - 64 / this.gearNum;

    //齿顶圆弧半径r3计算
    this.threeArcLineGearShape.r3 = this.chainISOParam.d1 * (1.3 * chainDriveDesignCommand.cos(this.threeArcLineGearShape.halfGama) + 0.8 * chainDriveDesignCommand.cos(this.threeArcLineGearShape.beta) - 1.3025) - 0.05;

    //工作段直线部分长度bc
    this.threeArcLineGearShape.bc = this.chainISOParam.d1 * (1.3 * chainDriveDesignCommand.sin(this.threeArcLineGearShape.halfGama) - 0.8 * chainDriveDesignCommand.sin(this.threeArcLineGearShape.beta));

    //计算e点至齿沟圆弧中心连线的距离H
    this.threeArcLineGearShape.H = Math.sqrt(Math.pow(this.threeArcLineGearShape.r3,2) -
      Math.pow(1.3 * this.chainISOParam.d1 - (this.chainISOParam.p * (1 + (2 * this.threeArcLineGearShape.ri - this.chainISOParam.d1) / this.chainWheelBasicParam.d)) / 2,2)
    );

  }
  //计算轴面齿廓尺寸
  calculateGearProfileParam(){
    let nCoefficient = 0.93;
    if(this.chainISOParam.p <= 12.7){
      //单排0.93b1，双排三排0.91b1，四排以上0.88b1
      if(this.chainRowNum >= 4){
        nCoefficient = 0.88;
      }else if(this.chainRowNum === 1){
        nCoefficient = 0.93;
      }else{
        nCoefficient = 0.91;
      }
    }else{
      //单排、双排三排、四排以上参考值为0.95b1或0.93b1
      if(this.chainRowNum <= 2){
        nCoefficient = 0.95;
      }else{
        nCoefficient = 0.93;
      }
    }

    //齿宽计算
    this.chainWheelProfileParam.bf1 = nCoefficient * this.chainISOParam.b1;

    //链轮齿总宽bfn = (n-1)pt + bf1
    this.chainWheelProfileParam.bfn = (this.chainRowNum - 1) * this.chainISOParam.pt + this.chainWheelProfileParam.bf1;

    //齿侧半径rx = p
    this.chainWheelProfileParam.rx = this.chainISOParam.p;

    //齿侧倒角链号为081、083、084、085时 ba = 0.06p,其他链号时ba = 0.13p
    let list = ["081","083","084","085"];
    if(list.indexOf(this.chainISOParam.name) === -1){
      this.chainWheelProfileParam.ba = 0.13 * this.chainISOParam.p;
    }else{
      this.chainWheelProfileParam.ba = 0.06 * this.chainISOParam.p;
    }

    //齿侧凸缘（或排间槽）圆角半径ra ≈ 0.04p
    this.chainWheelProfileParam.ra = 0.04 * this.chainISOParam.p;
  }
  //链轮结构尺寸计算
  calculateGearSizeParam(){

    let p = this.chainISOParam.p;
    let pList = [9.525,152875,25.4,38.1,50.8,76.2,12.7,19.05,31.75,44.45,63.5];
    let t = 9.525;


    if(this.chainWheelType === CHAINWHEELTYPE.IntegralSteelType){
      let k = 3.2;
      let d = this.chainWheelBasicParam.d;
      if(d < 50){
        k = 3.2;
      }else if(d < 100){
        k = 4.8;
      }else if(d < 150){
        k = 6.4;
      }else{
        k = 9.5;
      }

      this.integralSteelSprocketParam.h = k + this.chainWheelDiameter / 6 + 0.01 * this.chainWheelBasicParam.d;
      this.integralSteelSprocketParam.l = 3.3 * this.integralSteelSprocketParam.h;
      this.integralSteelSprocketParam.dh = this.chainWheelDiameter + 2 * this.integralSteelSprocketParam.h;
    }else if(this.chainWheelType === CHAINWHEELTYPE.BellySingleType){
      let tList = [7.9,10.3,12.7,15.9,22.2,31.8,9.5,11.1,14.3,19.1,28.6];
      if(pList.indexOf(p) !== -1)
      {
        t = tList[pList.indexOf(p)];
      }

      this.bellySingleCastingSprocketParam.h = 9.5 + this.chainWheelDiameter / 6 + 0.01 * this.chainWheelBasicParam.d;
      this.bellySingleCastingSprocketParam.l = 4 * this.bellySingleCastingSprocketParam.h;
      this.bellySingleCastingSprocketParam.dh = this.chainWheelDiameter + 2 * this.integralSteelSprocketParam.h;
      this.bellySingleCastingSprocketParam.br = 0.625 * this.chainISOParam.p + 0.93 * this.chainISOParam.b1;
      this.bellySingleCastingSprocketParam.c1 = (this.chainWheelBasicParam.d - this.chainWheelBasicParam.dg) / 2;
      this.bellySingleCastingSprocketParam.c2 = 0.9 * this.chainISOParam.p;
      this.bellySingleCastingSprocketParam.f = 4 + 0.25 * this.chainISOParam.p;
      this.bellySingleCastingSprocketParam.g = 2 * t;
      this.bellySingleCastingSprocketParam.R = 0.04 * this.chainISOParam.p;
      this.bellySingleCastingSprocketParam.t = t;
    }else if(this.chainWheelType === CHAINWHEELTYPE.BellyMultiType){
      let tList = [9.5,11.1,14.3,19.1,25.4,38.1,10.3,12.7,15.9,22.2,31.8];
      if(pList.indexOf(p) !== -1)
      {
        t = tList[pList.indexOf(p)];
      }

      this.bellySingleCastingSprocketParam.h = 9.5 + this.chainWheelDiameter / 6 + 0.01 * this.chainWheelBasicParam.d;
      this.bellySingleCastingSprocketParam.l = 4 * this.bellySingleCastingSprocketParam.h;
      this.bellySingleCastingSprocketParam.dh = this.chainWheelDiameter + 2 * this.integralSteelSprocketParam.h;
      this.bellySingleCastingSprocketParam.br = 0.625 * this.chainISOParam.p + 0.93 * this.chainISOParam.b1;
      this.bellySingleCastingSprocketParam.c1 = (this.chainWheelBasicParam.d - this.chainWheelBasicParam.dg) / 2;
      this.bellySingleCastingSprocketParam.c2 = 0.9 * this.chainISOParam.p;
      this.bellySingleCastingSprocketParam.f = 4 + 0.25 * this.chainISOParam.p;
      this.bellySingleCastingSprocketParam.g = 2 * t;
      this.bellySingleCastingSprocketParam.R = 0.5 * t;
      this.bellySingleCastingSprocketParam.t = t;
    }
  }

  //绘制模型
  async drawChainWheelModel() {
    //绘制三圆弧直线齿槽形状
    let sketchThreeCircleFeature = await this.drawArcLineSketch(this.chainWheelName + "草图1");

    //计算链轮上链条中心点应处的位置
    this.initChainCenterPntOnWheel();

    //首先绘制基础的链轮轮廓
    let sketchBasicFeature = await this.drawChainBasicProfileSketch(this.chainWheelName + "草图2");

    //拉伸的高度
    let extrudeHeight = 2;
    //绘制轴面齿廓形状
    let sketchProfileFeature = await this.drawAxisProfileSketch(this.chainWheelName + "草图3",extrudeHeight);

    //链轮圆台基础特征拉伸
    //let basicCircleFeature = await chainDriveDesignCommand.extrude(sketchBasicFeature,extrudeHeight,extrudeHeight,this.chainWheelName + "基台");
    let basicCircleFeature = await chainDriveDesignCommand.extrude(sketchBasicFeature,
      this.chainWheelBasicParam.chainWheelPlatformThickness / 2,
      this.chainWheelBasicParam.chainWheelPlatformThickness / 2,
      this.chainWheelName + "基台");
    //链轮齿沟特征拉伸
    //let gearGapFeature = await chainDriveDesignCommand.extrude(sketchThreeCircleFeature,extrudeHeight + 0.1,extrudeHeight + 0.1,this.chainWheelName + "齿沟");
    let gearGapFeature = await chainDriveDesignCommand.extrude(sketchThreeCircleFeature,
      this.chainWheelBasicParam.chainWheelPlatformThickness / 2,
      this.chainWheelBasicParam.chainWheelPlatformThickness / 2,
      this.chainWheelName + "齿沟");

    //进行旋转切除
    let revolveCutFeature = await chainDriveDesignCommand.revolveCut(sketchProfileFeature,
      this.threeArcLineGearShape.center,new THREE.Vector3(0,0,1),basicCircleFeature,this.chainWheelName + "旋转切除");

    //对链轮齿沟进行阵列
    let patternFeature = await chainDriveDesignCommand.loftCircularPattern(gearGapFeature,
      this.threeArcLineGearShape.center,new THREE.Vector3(0,0,1),
      this.gearNum,this.chainWheelName + "圆周阵列");

    //进行布尔运算
    let boolRes = await chainDriveDesignCommand.booleanSub(revolveCutFeature,gearGapFeature,this.chainWheelName + "布尔运算",patternFeature);

    //进行中间部分掏洞

    this.feature = boolRes;
  }
  async drawArcLineSketch(sketchName) {
    //以原点作为齿槽原点O点
    let O1Point1 = new THREE.Vector3();

    //s点为齿底，第一段sa为圆心为O半径为ri的圆弧
    //a点为齿沟圆弧终点
    //求a点坐标
    let ax = this.threeArcLineGearShape.ri * chainDriveDesignCommand.sin(this.threeArcLineGearShape.halfAlpha);
    let ay = this.threeArcLineGearShape.ri * chainDriveDesignCommand.cos(this.threeArcLineGearShape.halfAlpha);
    let aPoint1 = new THREE.Vector3(ax, -ay);

    //第二段ab为圆心为O2半径为1.3025d1+0.05的圆弧
    //O2点为工作段圆弧中心
    //求O2点的坐标
    let O2Point1 = new THREE.Vector3(-this.threeArcLineGearShape.M, this.threeArcLineGearShape.T);
    //根据圆弧坐标O2以及a点坐标、工作点圆弧中心角beta可以求出b点坐标，此时求得的工作段圆弧半径是过约束的r2 = sqrt(ri^2 + (M2+T2))
    let bPoint1 = chainDriveDesignCommand.rotatePointAroundPoint(O2Point1, aPoint1, this.threeArcLineGearShape.beta);

    //第三段bc为长度d1(1.3sin(γ/2) - 0.8sin(β))的线段
    let cPoint1 = chainDriveDesignCommand.rotatePointAroundPoint(bPoint1, O2Point1, -90, this.threeArcLineGearShape.bc);

    //求解e点坐标，使用齿沟圆弧中心的垂直平分线及H点可求解
    //齿沟圆弧中心一点为圆心位置，根据齿数可以平分求解相邻齿沟圆弧中心点坐标
    ////齿根点连线和齿沟圆弧中心点连线为相似正z边形，相似比齿根圆半径/(齿根圆半径+齿沟圆弧半径)
    //链轮中心点坐标
    let centerPoint = new THREE.Vector3(0, -(this.threeArcLineGearShape.ri + this.chainWheelBasicParam.df / 2));

    //另一齿沟圆弧中心点坐标
    let O1Point2 = chainDriveDesignCommand.rotatePointAroundPoint(centerPoint, O1Point1, -360 / this.gearNum);

    //O3点坐标
    let O3Point1 = new THREE.Vector3(this.threeArcLineGearShape.W, -this.threeArcLineGearShape.V);
    //求解e点坐标
    let ePoint1 = chainDriveDesignCommand.calculateCenterPtByDis(O1Point1, O1Point2, O3Point1, this.threeArcLineGearShape.r3);
    //将中心点和e点计算数据传回链轮，便于在其他运算中统一尺寸
    this.threeArcLineGearShape.center = centerPoint;
    this.threeArcLineGearShape.e = ePoint1;

    //分别求出abce点的关于y轴对称的点
    let aPoint2 = new THREE.Vector3(-aPoint1.x, aPoint1.y);
    let bPoint2 = new THREE.Vector3(-bPoint1.x, bPoint1.y);
    let cPoint2 = new THREE.Vector3(-cPoint1.x, cPoint1.y);
    let ePoint2 = new THREE.Vector3(-ePoint1.x, ePoint1.y);

    let O2Point2 = new THREE.Vector3(-O2Point1.x, O2Point1.y);
    let O3Point2 = new THREE.Vector3(-O3Point1.x, O3Point1.y);

    let sketch = chainDriveDesignCommand.command.sketch;
    await sketch.createSketch({sketchName: sketchName, datumId: 8});
    //每段创建草图元素
    await chainDriveDesignCommand.createArcByCenter(sketch, O3Point2, cPoint2, ePoint2);
    await chainDriveDesignCommand.createSketchLine(sketch, cPoint2, bPoint2)
    await chainDriveDesignCommand.createArcByCenter(sketch, O2Point2, bPoint2, aPoint2);
    await chainDriveDesignCommand.createArcByCenter(sketch, O1Point1, aPoint2, aPoint1);
    await chainDriveDesignCommand.createArcByCenter(sketch, O2Point1, aPoint1, bPoint1);
    await chainDriveDesignCommand.createSketchLine(sketch, bPoint1, cPoint1);
    await chainDriveDesignCommand.createArcByCenter(sketch, O3Point1, ePoint1, cPoint1);

    //齿轮的齿沟在进行布尔计算时作为负特征进行处理
    //通过两侧O3点与e点延长进行相交
    //计算交点
    let eO3InterPoint = await  chainDriveDesignCommand.calculateLineInterLine(O3Point2,ePoint2,O3Point1,ePoint1);
    await chainDriveDesignCommand.createSketchLine(sketch, ePoint1, eO3InterPoint);
    await chainDriveDesignCommand.createSketchLine(sketch, eO3InterPoint, ePoint2);

    await sketch.exitSketch();
    let res = await chainDriveDesignCommand.command.executeIncrementCommand(chainDriveDesignCommand.command.commandScript);
    await chainDriveDesignCommand.command.clearCommand();

    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let sketchFeature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return sketchFeature;
    }
  }
  async drawChainBasicProfileSketch(sketchName){
    //链轮中心点坐标
    let centerPoint = this.threeArcLineGearShape.center;
    //链轮齿凸点
    let circlePoint = this.threeArcLineGearShape.e;

    let sketch = chainDriveDesignCommand.command.sketch;
    await sketch.createSketch({sketchName:sketchName, datumId: 8});

    await chainDriveDesignCommand.createCircleByTwoPoint(sketch, centerPoint,circlePoint);

    //如果链轮需要打孔，进行打孔
    if(this.chainWheelBasicParam.dk > 0){
      let holeCirclePoint = new THREE.Vector3(centerPoint.x + this.chainWheelBasicParam.dk,centerPoint.y);
      await chainDriveDesignCommand.createCircleByTwoPoint(sketch, centerPoint,holeCirclePoint);
    }

    await sketch.exitSketch();
    let res = await chainDriveDesignCommand.command.executeIncrementCommand(chainDriveDesignCommand.command.commandScript);
    await chainDriveDesignCommand.command.clearCommand();

    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let sketchFeature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return sketchFeature;
    }
  }
  async drawAxisProfileSketch(sketchName,externDis){
    let bf1 = this.chainWheelProfileParam.bf1;
    let ra = this.chainWheelProfileParam.ra;
    let ba = this.chainWheelProfileParam.ba;
    let rx = this.chainWheelProfileParam.rx;

    //轴面齿廓尺寸计算
    //齿高度为da-df
    //let gearH = (chainWheel.chainWheelBasicParam.da - chainWheel.chainWheelBasicParam.df) / 2;
    //齿高度为齿顶点与齿根点在圆半径方向上的距离
    //e点偏转180/z角度
    let eProj = chainDriveDesignCommand.rotatePointAroundPoint(this.threeArcLineGearShape.center,this.threeArcLineGearShape.e,180 / this.gearNum);
    let gearH = eProj.y + this.threeArcLineGearShape.ri;
    //轴面齿廓rx的圆中心x值
    let rxOx = bf1 / 2 - rx;
    //轴面齿廓的圆弧部分的高度
    let rxH = Math.sqrt(Math.pow(rx,2) - Math.pow(rx - ba,2));
    //齿廓的直线部分高度
    let rxh = gearH - rxH;

    //分别列出当前轴面齿廓的点坐标，从左下角开始计算
    //左侧倒角圆心
    let chamferRaCenterPntL = new THREE.Vector3(-bf1 / 2 - ra,-rxh);
    //左侧倒角下侧点
    let chamferPntDL = new THREE.Vector3(-bf1 / 2 - ra,-rxh -ra);
    //左侧倒角上侧点
    let chamferPntUL = new THREE.Vector3(-bf1 / 2,-rxh);
    //左侧圆弧下点
    let arcPntDL = new THREE.Vector3(-bf1 / 2,0);
    //左侧圆弧上点
    let arcPntUL = new THREE.Vector3(ba - bf1 / 2,rxH);
    //左侧圆弧对应的中心
    let arcPntCenterPntL = new THREE.Vector3(-rxOx,0);

    //右侧使用左侧对称即可
    let arcPntCenterPntR = new THREE.Vector3(-arcPntCenterPntL.x,arcPntCenterPntL.y);
    let arcPntUR = new THREE.Vector3(-arcPntUL.x,arcPntUL.y);
    let arcPntDR = new THREE.Vector3(-arcPntDL.x,arcPntDL.y);
    let chamferPntUR = new THREE.Vector3(-chamferPntUL.x,chamferPntUL.y);
    let chamferPntDR = new THREE.Vector3(-chamferPntDL.x,chamferPntDL.y);
    let chamferRaCenterPntR = new THREE.Vector3(-chamferRaCenterPntL.x,chamferRaCenterPntL.y);

    this.chainWheelBasicParam.chainWheelPlatformThickness = (chamferPntDL.clone().sub(chamferPntDR)).length();

    //为了方便布尔运算，加入两个点使包围范围变大
    let externPntDL = new THREE.Vector3(chamferPntDL.x - externDis,chamferPntDL.y);
    let externPntUL = new THREE.Vector3(chamferPntDL.x - externDis,2 * arcPntUL.y);
    let externPntUR = new THREE.Vector3(chamferPntDR.x + externDis,2 * arcPntUL.y);
    let externPntDR = new THREE.Vector3(chamferPntDR.x + externDis,chamferPntDR.y);

    //为了保证轴面齿廓尺寸与三圆弧直线尺寸对齐，轴面齿廓尺寸需要在y方向移动ri - rxh距离,所有点均需要此y向偏移
    let vectModify = new THREE.Vector3(0,rxh - this.threeArcLineGearShape.ri);
    chamferRaCenterPntL.add(vectModify);
    chamferPntDL.add(vectModify);
    chamferPntUL.add(vectModify);
    arcPntDL.add(vectModify);
    arcPntUL.add(vectModify);
    arcPntCenterPntL.add(vectModify);
    arcPntCenterPntR.add(vectModify);
    arcPntUR.add(vectModify);
    arcPntDR.add(vectModify);
    chamferPntUR.add(vectModify);
    chamferPntDR.add(vectModify);
    chamferRaCenterPntR.add(vectModify);
    externPntDL.add(vectModify);
    externPntUL.add(vectModify);
    externPntUR.add(vectModify);
    externPntDR.add(vectModify);

    //在YOZ平面进行绘制轴面齿廓草图
    let sketch = chainDriveDesignCommand.command.sketch;
    await sketch.createSketch({sketchName: sketchName, datumId: 22});
    //每段创建草图元素
    await chainDriveDesignCommand.createArcByCenter(sketch, chamferRaCenterPntL, chamferPntDL, chamferPntUL);
    await chainDriveDesignCommand.createSketchLine(sketch, chamferPntUL, arcPntDL);
    await chainDriveDesignCommand.createArcByCenter(sketch, arcPntCenterPntL, arcPntUL, arcPntDL);
    await chainDriveDesignCommand.createSketchLine(sketch, arcPntUL, arcPntUR);
    await chainDriveDesignCommand.createArcByCenter(sketch, arcPntCenterPntR, arcPntDR, arcPntUR);
    await chainDriveDesignCommand.createSketchLine(sketch, arcPntDR, chamferPntUR);
    await chainDriveDesignCommand.createArcByCenter(sketch, chamferRaCenterPntR, chamferPntUR, chamferPntDR);

    //用于合并的外轮廓
    await chainDriveDesignCommand.createSketchLine(sketch, chamferPntDR, externPntDR);
    await chainDriveDesignCommand.createSketchLine(sketch, externPntDR, externPntUR);
    await chainDriveDesignCommand.createSketchLine(sketch, externPntUR, externPntUL);
    await chainDriveDesignCommand.createSketchLine(sketch, externPntUL, externPntDL);
    await chainDriveDesignCommand.createSketchLine(sketch, externPntDL, chamferPntDL);

    await sketch.exitSketch();
    let res = await chainDriveDesignCommand.command.executeIncrementCommand(chainDriveDesignCommand.command.commandScript);
    await chainDriveDesignCommand.command.clearCommand();

    let currentFeature = res?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      let sketchFeature = {
        id: currentFeature[0]?.id,
        name: currentFeature[0]?.name,
      }
      return sketchFeature;
    }
  }


  //计算链轮上链条中心点应处的位置
  initChainCenterPntOnWheel(){
    //每个链轮的齿度数
    let singleAngle = 360 / this.gearNum;
    let rotateLineDir = new THREE.Vector3(0,0,1);
    let originPoint = new THREE.Vector3();
    //当链轮中心固定，且链轮轴点固定，且齿数已经固定，这三个值之间会有过约束，所以应该移动链轮轴点来进行合约束。
    let chainWheelRadius = 0.5 * this.chainISOParam.p / chainDriveDesignCommand.sin(360 / this.gearNum * 0.5);
    this.chainWheelRadius = chainWheelRadius;
    //从链轮中心重新确定初始链轮轴点
    originPoint = this.threeArcLineGearShape.center.clone().add((originPoint.clone().sub(this.threeArcLineGearShape.center)).normalize().multiplyScalar(chainWheelRadius));

    //已知的一个点是原点位置,使用原点绕旋转点进行链轮齿数次旋转，得到所有点
    for(let i = 0;i < this.gearNum ;i++)
    {
      let curRotatePoint = chainDriveDesignCommand.getLineRevolvePoint(rotateLineDir,this.threeArcLineGearShape.center,originPoint,singleAngle * i);
      this.listChainCenterPoint.push(curRotatePoint);
    }
  }
  //整体对当前链轮上的啮合轴心进行变换，绕z向的轴旋转或平移,当前方法只会进行旋转或平移计算，不会同时存在
  async transAllChainWheelChainCenterPnt(angle,moveVector = new THREE.Vector3()){
    let newList = [];
    let rotateLineDir = new THREE.Vector3(0,0,1);
    this.listChainCenterPoint.forEach(point => {
      if(angle != 0){
        point = chainDriveDesignCommand.getLineRevolvePoint(rotateLineDir,this.threeArcLineGearShape.center,point,angle);
      }else{
        point.add(moveVector);
      }

      newList.push(point);
    })
    this.listChainCenterPoint = newList;
  }

  async moveFeature(moveVector) {
    this.feature = await chainDriveDesignCommand.moveFeature(this.feature,
      moveVector.clone().normalize(),
      moveVector.length(),
      this.chainWheelName + "移动",
      false);

    //对当前链轮的所有点进行操作
    this.threeArcLineGearShape.e = this.threeArcLineGearShape.e.clone().add(moveVector);
    this.threeArcLineGearShape.center = this.threeArcLineGearShape.center.clone().add(moveVector);
    await this.transAllChainWheelChainCenterPnt(0,moveVector);
  }
  async rotateFeature(angle,rotateName = "旋转"){
    this.feature = await chainDriveDesignCommand.rotateFeature(this.feature,
      this.threeArcLineGearShape.center,
      new THREE.Vector3(0,0,1),
      angle,
      this.chainWheelName + rotateName,
      false);

    //旋转需要带着链轮上需要旋转的元素一起旋转
    this.threeArcLineGearShape.e = chainDriveDesignCommand.getLineRevolvePoint(new THREE.Vector3(0,0,1),this.threeArcLineGearShape.center,this.threeArcLineGearShape.e,angle);
    await this.transAllChainWheelChainCenterPnt(angle);
  }
}
export class ChainParam{
  constructor() {
  }
  //设置链子规格
  setChainISOParam(param){
    this.chainISOParam = param;
  }
  //设置外链板厚度占外链板内宽的比例
  setOutChainBoardThickness(outsideThickness){
    this.outsideChainBoardThickness = outsideThickness * this.chainISOParam.b3;
  }
  setInChainBoardThickness(outsideThickness){
    this.insideChainBoardThickness = outsideThickness * this.chainISOParam.b3;
  }
  //设置内外链板在中间凹陷部分的高度占内外链板高度的比例
  setChainBoardCaveHeight(insideCaveHeight,outsideCaveHeight){
    this.insideChainBoardCaveHeight = insideCaveHeight * this.chainISOParam.h2;
    this.outsideChainBoardCaveHeight = outsideCaveHeight * this.chainISOParam.h3;
  }
  //根据两点绘制外链
  //isLock,当前外链段是否止锁件
  async drawOutsideChain(point1,point2,chainName,isLock = false){
    //销轴的高度为外链板内宽+外链板厚度，如果是止锁件，应该再加入止锁件附加宽度
    let pinHeight = this.chainISOParam.b4;
    if(isLock){
      //默认为两端都有止锁件
      pinHeight += this.chainISOParam.b7;
    }
    //外链包含外链板、销轴
    //首先绘制销轴
    let pin1 = await chainDriveDesignCommand.drawHollowColumn(point1,pinHeight / 2,chainName + "销轴1",this.chainISOParam.d2);
    //let pin2 = await chainDriveDesignCommand.drawHollowColumn(point2,pinHeight / 2,chainName + "销轴2",this.chainISOParam.d2);
    let dir = point2.clone().sub(point1);
    let pin2 = await chainDriveDesignCommand.moveFeature(pin1,
      dir.clone().normalize(),
      dir.length(),
      chainName + "销轴2",
      true);

    //绘制外链板的两个链板
    let chainBoard1 = await chainDriveDesignCommand.drawChainBoard(point1,
      point2,
      this.chainISOParam.d2,
      this.chainISOParam.h3 / 2,
      this.outsideChainBoardCaveHeight,
      this.outsideChainBoardThickness,
      chainName + "外链板");

    //对外链板进行非复制移动
    chainBoard1 = await chainDriveDesignCommand.moveFeature(chainBoard1,
      new THREE.Vector3(0,0,1),
      this.chainISOParam.b3 / 2,
      chainName + "外链板1",
      false);
    //进行复制移动
    let chainBoard2 = await chainDriveDesignCommand.moveFeature(chainBoard1,
      new THREE.Vector3(0,0,1),
      -(this.chainISOParam.b3 + this.outsideChainBoardThickness),
      chainName +"外链板2",
      true);

    let listFeature = [];
    listFeature.push(pin1);
    listFeature.push(pin2);
    listFeature.push(chainBoard1);
    listFeature.push(chainBoard2);
    let unionFeature = chainDriveDesignCommand.booleanUnion(listFeature,"外链合并");

    return unionFeature ;
  }
  //根据两点绘制内链
  async drawInsideChain(point1,point2,chainName){
    //内链包含内链板、滚子、套筒
    //绘制套筒
    let sleeve1 = await chainDriveDesignCommand.drawHollowColumn(point1,this.chainISOParam.b2 / 2,chainName + "套筒1",this.chainISOParam.d2,this.chainISOParam.d3);
    //let sleeve2 = await chainDriveDesignCommand.drawHollowColumn(point2,this.chainISOParam.b2 / 2,chainName + "套筒2",this.chainISOParam.d2,this.chainISOParam.d3);
    let dir = point2.clone().sub(point1);
    let sleeve2 = await chainDriveDesignCommand.moveFeature(sleeve1,
      dir.clone().normalize(),
      dir.length(),
      chainName + "套筒2",
      true);
    //绘制滚子
    //let roller1 = await chainDriveDesignCommand.drawHollowColumn(point1,this.chainISOParam.b1 / 2,chainName + "滚子1",this.chainISOParam.d3,this.chainISOParam.d1);
    let roller1 = await chainDriveDesignCommand.drawHollowColumn(point1,this.chainISOParam.b2 / 2 - this.insideChainBoardThickness,chainName + "滚子1",this.chainISOParam.d3,this.chainISOParam.d1);
    let roller2 = await chainDriveDesignCommand.moveFeature(roller1,
      dir.clone().normalize(),
      dir.length(),
      chainName + "滚子2",
      true);

    //绘制内链板的两个链板
    let insideChainBoard1 = await chainDriveDesignCommand.drawChainBoard(point1,
      point2,
      this.chainISOParam.d3,
      this.chainISOParam.h2 / 2,
      this.insideChainBoardCaveHeight,
      //(this.chainISOParam.b2 - this.chainISOParam.b1) / 2,
      //(this.chainISOParam.b2 - this.chainISOParam.b1) / 4,
      this.insideChainBoardThickness,
      "内链板");

    //对内链板进行非复制移动
    let insideChainBoard2 = await chainDriveDesignCommand.moveFeature(insideChainBoard1,
      new THREE.Vector3(0,0,1),
      //this.chainISOParam.b1 / 2,
      this.chainISOParam.b2 / 2 - this.insideChainBoardThickness,
      "内链板1",
      true);
    //进行复制移动
    insideChainBoard1 = await chainDriveDesignCommand.moveFeature(insideChainBoard1,
      new THREE.Vector3(0,0,1),
      -this.chainISOParam.b2 / 2,
      "内链板2",
      false);

    let listFeature = [];
    listFeature.push(sleeve1);
    listFeature.push(sleeve2);
    listFeature.push(roller1);
    listFeature.push(roller2);
    listFeature.push(insideChainBoard1);
    listFeature.push(insideChainBoard2);
    let unionFeature = chainDriveDesignCommand.booleanUnion(listFeature,"内链合并");

    return unionFeature ;
  }



}

</script>
<style scoped>
.wrap {
    font-size: 12px;
}
.result-item .angle-icon {
    font-weight: bold;
    padding: 0 2px;
}

.dialog-query-list .move-buttons {
    margin-right: 35px;
}
.group {
    display: flex;
    justify-content: center;
}
.group-btn:hover {
    background-color: var(--bg-color8);
    cursor: pointer;
}
.group-btn {
    width: 24px;
    height: 24px;
    border: var(--bg-color8) 1px solid;
    border-radius: 3px;
    font-size: 16px;
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 2px;
}
.group-text {
    margin: 0 5px;
}
.group-btn:active {
    box-shadow: 2px 2px #999 inset;
}
.radio >>> .el-radio__label {
    padding-left: 2px;
}
.curve-button {
    padding-left: 10px;
}
</style>
